抄得快,不代表抄得對
畫得多,不代表畫得好
程式碼跑得動,不代表它值得留到明天
AI 可以在三秒內生出一百行程式碼,但沒有一行程式碼會在三秒內告訴你,它三個月後會變成什麼樣子
在過去,「寫不出來」是最大的門檻
而現在,門檻幾乎消失了,只要你會問問題,AI 就會給你一個能跑的答案
但「能跑」從來不是程式碼品質的終點,而是剛開始而已
當產出速度不再是瓶頸,真正稀缺的東西,變成了判斷力:
這段程式碼,值不值得留下來?
我們不談怎麼用 AI 寫更多程式碼,談的是怎麼看穿程式碼裡的壞味道(不管它是人寫的,還是 AI 生的)
先說清楚,避免你讀到一半才發現不是你要的內容
符合以下任一種情況,這系列會對你有用:
如果你完全沒寫過物件導向程式碼,連 class 跟 interface 的差別都還不熟,這系列會有點吃力
建議先找一份 OOP 入門教材打底,再回來看,判斷力的部分會更有感覺
如果你還不熟 SOLID 五大原則,不用太別擔心,明天會先把這五條規矩刻清楚,才正式進入 Day 03 第一站(已經熟的讀者,Day 02 當複習快速掃過就好,不影響後面的閱讀節奏)
中世紀的修道院抄寫房(scriptorium),靠人力大量抄寫手稿
抄得快,知識才傳得開
但抄寫房有一個致命傷:
抄寫員照抄,不見得理解內容
一個錯字、一個誤譯,會被下一位抄寫員原封不動地複製下去
一代傳一代,沒有人發現,也沒有人有權力去改
文藝復興打破了這個模式
畫室(bottega)裡的學徒不是複製前人的畫,而是先學觀察、學比例、學解剖,然後才被允許動筆
師傅會站在畫作前,指著說:
「這裡的透視錯了」
「這個人物比例不對」
一筆一筆,要求修正
文藝復興的偉大,不是因為畫家畫得比較快
是因為他們建立了一套看得出好壞的判斷標準,並且願意為了品質重畫
今天的 AI 輔助開發,很像回到了抄寫房
只要給出提示,程式碼就會被大量「抄」出來,能跑、能過編譯,卻沒有人問過一句:
「這樣寫,好嗎?」
本系列要做的,就是把畫室的判斷力找回來
用一套系統化的語言,指出程式碼裡「透視錯了」「比例不對」的地方
Code Smell(程式碼壞味道)不是語法錯誤
不會讓編譯失敗,也不是「一定要照做」的規範清單
它更像畫室師傅的眼光
看到某段程式碼,會直覺覺得「怪怪的」:
本系列採用 5W1H 分析框架,把每一種壞味道拆解成六個問題:
23 個 Code Smell,分成 5 個模組,我們用文藝復興的 5 個場景重新命名它們,讓抽象的分類有具體的畫面可以想像
先不談理論,看一段很典型的場景
需求是「訂單成立時,扣庫存、算折扣、寄通知信」,向 AI 助手描述完需求後,貼回來的程式碼長這樣:
public class OrderProcessor
{
private readonly AppDbContext _db;
private readonly ILogger _log;
private readonly IEmailService _emailService;
private readonly ISmsService _smsService;
public OrderProcessor(AppDbContext db, ILogger log,
IEmailService emailService, ISmsService smsService)
{
_db = db;
_log = log;
_emailService = emailService;
_smsService = smsService;
}
public decimal Process(int customerId, int productId, int qty,
string customerType, string couponCode, bool sendEmail, bool sendSms)
{
var customer = _db.Customers.Find(customerId);
var product = _db.Products.Find(productId);
if (customer == null || product == null)
throw new InvalidOperationException("not found");
if (product.Stock < qty)
throw new InvalidOperationException("out of stock");
decimal price = product.Price * qty;
if (customerType == "VIP")
price = price * 0.9m;
else if (customerType == "REGULAR" && couponCode == "WELCOME10")
price = price * 0.95m;
product.Stock = product.Stock - qty;
_db.SaveChanges();
_log.Info("order processed: customer=" + customerId +
" product=" + productId + " qty=" + qty + " price=" + price);
if (sendEmail)
_emailService.Send(customer.Email, "Order Confirmed", "...");
if (sendSms)
_smsService.Send(customer.Phone, "...");
return price;
}
}
這段程式碼能編譯、能跑、demo 也會過
但用畫室師傅的眼光看一遍,至少有三個「透視錯了」的地方:
customerType == "VIP",打錯字不會編譯錯誤,只會在 production 悄悄算錯折扣——這是Primitive Obsession 的典型現場Process(int, int, int, string, string, bool, bool)——換個人接手,光是搞懂每個參數是什麼就要先讀完整個方法,這是 Long Parameter List
今天先不動手改,這正是我們接下來要一起練習的「診斷」能力
| 模組 | 文藝復興隱喻 | 一句話主題 |
|---|---|---|
| 模組一:臃腫者(Bloaters) | 布魯內雷斯基的圓頂 | 比例,先於體積 |
| 模組二:物件導向的濫用者(Object-Orientation Abusers) | 達文西的透視法 | 先懂結構,才畫得對形體 |
| 模組三:變更的妨礙者(Change Preventers) | 濕壁畫的時間壓力 | 顏料乾了之後,就改不動了 |
| 模組四:可有可無(Dispensables) | 阿伯提的節制美學 | 多餘的裝飾不是美,是負擔 |
| 模組五:過度的耦合者(Couplers) | 畫室的分工倫理 | 師傅與學徒,不該互相代筆 |
在你下一次看到「AI 生出來,能跑」的程式碼時,先問自己:
明天先不急著拆程式碼,也先不進畫室——我們去看看畫室門楣上刻的五條規矩
SOLID 五大原則是接下來 23 個 Code Smell 共同的判斷基礎,先把規矩刻清楚,後面認味道才不會只是死背名詞
行會規範,明天見